#include <stdlib.h>
#include <stdio.h>
#include "COS/CosEventComm.hh"
#include "COS/CosEventChannelAdmin.hh"

#include "CORBA_util.h"
#include "eventConsumer.h"

#define RETRIES 100 //numero de reintentos de conexion/desconexion

EventConsumer::EventConsumer(CORBA::ORB_ptr __orb)
{	
	orb = __orb;
	
	create_consumer();
}

EventConsumer::~EventConsumer()
{
	disconnect_from_push_supplier();
}

void EventConsumer::disconnect_from_push_supplier()
{
	int i;
	
	for(i=0; i<RETRIES; i++) 
	{
		try {
	    	proxy_supplier->disconnect_push_supplier();
	      	break;
	   	}
	   	catch (CORBA::COMM_FAILURE& ex) 
		{
        	printf("Fallo de conexion: Reintento %d de %d\n", i+1, RETRIES);
			if ((i+1) >= RETRIES)
			{
				exit(1);
			}
	   	}
	}
}

void EventConsumer::create_consumer()
{	
	try {
		PortableServer::POA_var rootPoa = auxiliary::resolve_init<PortableServer::POA>(orb, "RootPOA");

		PortableServer::POAManager_var pman =rootPoa->the_POAManager();
		pman->activate();

		CosNaming::NamingContext_var rootContext = auxiliary::resolve_init<CosNaming::NamingContext>(orb, "NameService");

		CosNaming::Name name;
		name.length(1);
		name[0].id = CORBA::string_dup("EventChannel");
		name[0].kind = CORBA::string_dup("EventChannel");
		
		channel = auxiliary::resolve_name<CosEventChannelAdmin::EventChannel>(rootContext, name);
	}
	catch(CORBA::ORB::InvalidName& ex) 
	{
		printf("InvalidName: %s\n", ex._name());
	    exit(1);
	}
	catch(CORBA::SystemException& ex) 
	{
		printf("SystemException: %s\n", ex._name());
		exit(1);
	}
	catch(CORBA::Exception& ex) 
	{
		printf("Exception: %s\n", ex._name());
		exit(1);
	}

	int i;
	for (i=0; i<RETRIES; i++)
	{
		try {
			consumer_admin = channel->for_consumers();
		   	if (CORBA::is_nil(consumer_admin))
		   	{
				printf("CONSUMER_ADMIN NIL\n");
				exit(1);
		   	}
		   	break;
		}
		catch (CORBA::COMM_FAILURE& ex) 
		{
			printf("Fallo de conexion: Reintento %d de %d\n", i+1, RETRIES);
			if ((i+1) >= RETRIES)
			{
				exit(1);
			}
		}
	}
	
	for (i=0; i<RETRIES; i++)
  	{
		try {
        	proxy_supplier = consumer_admin->obtain_push_supplier ();
        	if (CORBA::is_nil (proxy_supplier))
        	{
				printf("PROXY SUPPLIER NIL\n");
           		exit (1);
        	}

			break;
		}
	
    	catch (CORBA::COMM_FAILURE& ex) 
		{
        	printf("Fallo de conexion: Reintento %d de %d\n", i+1, RETRIES);
			if ((i+1) >= RETRIES)
			{
				exit(1);
			}
		}
	}

	for (i=0; i<RETRIES; i++)
  	{
     	try {
        	proxy_supplier->connect_push_consumer(this->_this());
        	break;
     	}
     	catch (CORBA::BAD_PARAM& ex) 
		{
			printf("BAD_PARAM: %s\n", ex._name());
		    exit(1);
     	}
     	catch (CosEventChannelAdmin::AlreadyConnected& ex) 
		{
			break;
     	}
     	catch (CORBA::COMM_FAILURE& ex) 
		{
        	printf("Fallo de conexion: Reintento %d de %d\n", i+1, RETRIES);
			if ((i+1) >= RETRIES)
			{
				exit(1);
			}
     	}
  	}
}
